package ru.mera.aaclog;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import ru.mera.aaclog.db.LogHeader;
import ru.mera.aaclog.db.MessageHeader;
import ru.mera.aaclog.dbdao.GenericDAO;

/**
 *
 * @version 1.0 03/03/2013
 * @author anavdeev
 */
@ManagedBean
@SessionScoped
public class ViewerPageBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private String log_id;
    private String pattern;
    private final EntityManagerFactory emf;
    private final EntityManager em;
    private GenericDAO<MessageHeader> messageHeaderDAO;
    private GenericDAO<LogHeader> logHeaderDAO;
    private LogHeader logHeader;
    private StringBuilder buff;
    {
        emf = Persistence.createEntityManagerFactory("aaclogdb");
        em = emf.createEntityManager();
        messageHeaderDAO = new GenericDAO(em);
        logHeaderDAO = new GenericDAO(em);
    }

    public String getId() {
        return log_id;
    }

    public void setId(String log_id) {
        this.log_id = log_id;
        logHeader = logHeaderDAO.getSingle(LogHeader.GET_BY_ID, new Integer(log_id));
    }

    public GenericDAO<MessageHeader> getMessageHeaderDAO() {
        return messageHeaderDAO;
    }

    public void setMessageHeaderDAO(GenericDAO<MessageHeader> messageHeaderDAO) {
        this.messageHeaderDAO = messageHeaderDAO;
    }

    public String getName() {
        String name = "";
        if (logHeader != null) {
            try {
                name = logHeader.getName();
            } catch (Exception e) {
                Logger.getLogger(ViewerPageBean.class.getName()).log(Level.SEVERE, null, e);
            }
        }
        return name;
    }
    
    public Date getDate() {
        Date date = Calendar.getInstance().getTime();
        if (logHeader != null) {
            try {
                date = logHeader.getDate();
            } catch (Exception e) {
                Logger.getLogger(ViewerPageBean.class.getName()).log(Level.SEVERE, null, e);
            }
        }
        return date;
    }
    
    public String getFilename() {
        String filename = "";
        if (logHeader != null) {
            try {
                filename = logHeader.getFilename();
            } catch (Exception e) {
                Logger.getLogger(ViewerPageBean.class.getName()).log(Level.SEVERE, null, e);
            }
        }
        return filename;
    }
    
    public MessageHeader[] getMessageList() {
        MessageHeader[] messages = new MessageHeader[0];
        try {
            if (messageHeaderDAO != null ) {
                if (getPattern() != null && !getPattern().isEmpty()) {
                    messages = messageHeaderDAO.get(
                                MessageHeader.GET_BY_PATTERN, 
                                new LogHeader(new Integer(getId())), 
                                "%" + pattern + "%"
                               ).toArray(new MessageHeader[0]);
                } else {
                    messages = messageHeaderDAO.get(
                                MessageHeader.GET_BY_LOG, 
                                new LogHeader(new Integer(getId()))
                               ).toArray(new MessageHeader[0]);
                }
            }
            calculateStyles(messages);
        } catch (Exception e) {
            Logger.getLogger(ViewerPageBean.class.getName()).log(Level.SEVERE, "getMessageList", e);
        }
        return messages;
    }

    private void calculateStyles(MessageHeader[] messages) {
        buff = new StringBuilder();
        int colorCounter = 21, currentCounter = 1;
        Map<String, Integer> tags = new HashMap<String, Integer>();
        for(MessageHeader message : messages) {
            if (buff.length() > 0) {
                buff.append(",");
            }

            String toTagValue = message.getToTag(), fromTagValue = message.getFromTag();
            if (toTagValue == null) {
                toTagValue = "";
            }
            if (fromTagValue == null) {
                fromTagValue = "";
            }
            String cseq = message.getcSeq();
            // skip OPTIONS messages and empty messages
            if ((cseq != null && cseq.endsWith("OPTIONS")) || (toTagValue.isEmpty() && fromTagValue.isEmpty())) {
                if (message.getSipMessageType().equalsIgnoreCase("Outgoing")) {
                    buff.append("order-table-odd-row");
                } else  {
                    buff.append("order-table-even-row");
                }
            } else {
                Integer toStyleNumber = tags.get(toTagValue),
                        fromStylenumber = tags.get(fromTagValue);
                if (toStyleNumber == null) {
                    if (fromStylenumber == null) {
                        //  null + null case
                        toStyleNumber = currentCounter;
                        if (!toTagValue.isEmpty()) {
                            tags.put(toTagValue, toStyleNumber);
                        }
                        if (!fromTagValue.isEmpty()) {
                            tags.put(fromTagValue, toStyleNumber);
                        }
                        // increment current counter
                        if (currentCounter < colorCounter) {
                            currentCounter++;
                        } else {
                            currentCounter = 1;
                        }
                    } else {
                        //  null + !null case
                        toStyleNumber = fromStylenumber;
                        if (!toTagValue.isEmpty()) {
                            tags.put(toTagValue, toStyleNumber);
                        }
                    }
                } else {
                    if (fromStylenumber == null) {
                        //  !null + null case
                        if (!fromTagValue.isEmpty()) {
                            tags.put(fromTagValue, toStyleNumber);
                        }
                    } else {
                        //  !null + !null case
                        if (toStyleNumber.compareTo(fromStylenumber) != 0) {
                            Logger.getLogger(ViewerPageBean.class.getName()).log(Level.SEVERE, "style detection error!");
                        }
                    }
                }
                buff.append("row_color_");
                buff.append(toStyleNumber);
            }
        }
    }

    public String getPattern() {
        return pattern;
    }

    public void setPattern(String pattern) {
        this.pattern = pattern;
    }
    
    public String applayFilter(Boolean reset) {
        if (!reset && getPattern() != null && !getPattern().isEmpty()) {
            return "success";
        }
        setPattern("");
        return "reset"; // this case for demo purpose only
    }
    
    public String gohome() {
        setPattern("");
        return "gohome";
    }
    
    public String getRowColor() {
        return buff.toString();
        //return "order-table-odd-row,order-table-even-row";
    }
}
